home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Creative Computers
/
Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso
/
commercial
/
sunrize
/
psound_3.1
/
public_domain
/
sound
/
sound.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-17
|
19KB
|
575 lines
/**************************** Sound.c *********************************
Sound is copyright (c) 1988 by Richard Lee Stockton, 21305 60th Ave W.,
Mountlake Terrace, Washington 98043, 206/776-1253(voice), but may be freely
distributed as long as no profit is made from its distribution or sale
without my written permission. I call this concept 'FreeWare', you can
call it whatcha want.
I also include the source code, (Manx 3.4/3.6), in the hope that it
will be of benefit to someone in the Amiga programming community. Feel free
to alter it at will, (but at your own risk!). I _would_ appreciate
receiving a copy of whatever it may become and it is always nice to receive
credit, (perhaps just a few lines of glowing tribute.^)
Long Live Leo and All the Little Schwabies!
To Manufacture with Manx 3.4/3.6:
cc Sound.c
ln +cd Sound.o -lc
You'll get a warning that you've re-defined IconBase. Ignore it.
**************************************************************************/
#include <exec/memory.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <libraries/dosextens.h>
#include <devices/audio.h>
#include <functions.h>
/* Less than WorkBench 1.2 need not apply. That's nobody, right? ;-> */
#define REVISION 33L
/* We'll need 4 buffers in CHIP memory, all else in FAST, if ya got it */
#define BUFSIZE 1024L
/* Some MANX specific, byte saving, (usually), string routines */
#define strcpy _BUILTIN_strcpy
#define strcmp _BUILTIN_strcmp
#define strlen _BUILTIN_strlen
/* A pretty little HELP message showing valid variable ranges */
#define USAGE "\
\033[42m\033[31m\
USAGE: Sound <file> [l/r] [0-55] [56-65535] [on/off] [QUIET] \
\033[m\n\033[42m\
ABORT: <CTRL> 'c'\033[33m\
CHANNEL CYCLES SAMPLES/SECOND STEREO NO-WINDOW \
\033[m\n\033[42m\033[31m\
20-JAN-90 03:08 \xA9 1990 Richard Lee Stockton - freely distributable \
\033[m\n"
/* Probably more GLOBALS than are required. 'C' is funny stuff. */
extern struct IconBase *IconBase=NULL;
extern struct IntuitionBase *IntuitionBase=NULL;
extern struct WBStartup *WBenchMsg=NULL;
extern struct WBArg *argp=NULL;
struct IntuiMessage *message=NULL;
struct Window *StatusWindo=NULL;
struct DiskObject *infofile=NULL;
struct IOAudio *sound[4]={NULL,NULL,NULL,NULL};
long sactual=0L, sstart=0L, savelock=0L,
atol(), sps=0L, cycles=1L, lock=0L;
short k=0, stereo=0, left=1, right=1,
statusline=1;
UBYTE sunit[4]={12,10,5,3},
sunitL[2]={1,8}, sunitR[2]={2,4};
BOOL help=FALSE;
char *sbuffer=NULL, *ltoa(), title[50]="Sound: ",
*cbuf[4]={NULL,NULL,NULL,NULL},
*sname[108]=NULL, *SafeAllocMem();
void loadSound(), setStatusWindo(),
soundSound(), cleanup(), quit();
/*********** quit, give-up, go home, finish... Neatness counts! ******/
void quit(qstring)
char *qstring;
{ cleanup(qstring); exit(0); }
void cleanup(string)
char *string;
{
if(sound[0]) /* This cleans up the audio device stuff */
{
for(k=3;k>(-1);k--)
{
if((sound[k])&&(sound[k]->ioa_Request.io_Device))
AbortIO(sound[k]);
}
if(sound[0]->ioa_Request.io_Device) CloseDevice(sound[0]);
for(k=3;k>(-1);k--)
{
if(sound[k]->ioa_Request.io_Message.mn_ReplyPort)
DeletePort(sound[k]->ioa_Request.io_Message.mn_ReplyPort);
}
for(k=3;k>(-1);k--)
{
if(sound[k]) FreeMem(sound[k],(long)sizeof(struct IOAudio));
if(cbuf[k]) FreeMem(cbuf[k],BUFSIZE);
}
sound[0]=sound[1]=sound[2]=NULL;
}
/* Write any message to out. May be error or could be samples/second */
/* You'll be sorry if you try to Write(Output()) to WorkBench! 8-) */
if(help) Write(Output(),string,(long)strlen(string));
else if(strlen(string))
{
strcpy(title,"Sound Error: "); strcat(title,string);
setStatusWindo(); Delay(150L);
}
/* Clean up everything else */
if(StatusWindo) CloseWindow(StatusWindo);
if(IntuitionBase) CloseLibrary(IntuitionBase);
if(sbuffer) FreeMem(sbuffer,sactual);
if(infofile) FreeDiskObject(infofile);
if(IconBase) CloseLibrary(IconBase);
if(!sound[3]) exit(10);
StatusWindo=NULL; IntuitionBase=NULL;
sbuffer=NULL; infofile=NULL; IconBase=NULL;
sactual=0L; sstart=0L; savelock=0L; sps=0L; cycles=1L;
lock=0L; k=0; stereo=0; left=1; right=1;
}
/* Don't Allocate if Low Mem - by Bryce Nesbitt */
/* Aberations by RLS. 4096 should be fudge enough */
char *SafeAllocMem(size,flags)
long size, flags;
{
register char *p;
if(p=(char *)AllocMem(size,flags))
if(AvailMem(MEMF_CHIP)<4096L)
{ FreeMem(p,size); return(NULL); }
return(p);
}
/**** Status Window. Uses <CTRL> 'c' to abort. ****/
void setStatusWindo()
{
struct NewWindow w;
/* Try to Open Intuition and if successful, make a 'status' window */
if(StatusWindo) CloseWindow(StatusWindo); StatusWindo=NULL;
if(!IntuitionBase)
{
IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library",REVISION);
}
if(!IntuitionBase) quit("");
w.LeftEdge = 82L;
w.TopEdge = 0L;
/* if title==USAGE, the large Width value will abort the window open */
/* This is just fine, because we don't WANT it to open in this case. */
w.Width = (long)(strlen(title)*8+8);
w.Height = 10L;
w.DetailPen = 0x01;
w.BlockPen = 0x03;
w.Title = (UBYTE *)title;
w.Flags = SMART_REFRESH|NOCAREREFRESH|ACTIVATE|WINDOWDRAG;
w.IDCMPFlags = VANILLAKEY; /* So we can get <CTRL> 'c' message */
w.Type = WBENCHSCREEN;
w.FirstGadget = NULL;
w.CheckMark = NULL;
w.Screen = NULL;
w.BitMap = NULL;
w.MinWidth = 0;
w.MinHeight = 0;
w.MaxWidth = 0;
w.MaxHeight = 0;
StatusWindo = OpenWindow(&w);
/* Abort ONLY if cycles = 0 (loop) AND the window failed to open. */
/* This set of conditions would otherwise result in an Endless and */
/* Escape-proof loop. If cycles != 0, sound will end, sometime... */
if(!StatusWindo&&(cycles==0L)) quit("");
}
/******** Load SoundFile 'sPath' & set cycles-sps-stereo *******/
void loadSound(sPath)
char *sPath[80];
{
struct Filehandle *sFile=NULL;
struct FileInfoBlock *finfo=NULL;
struct FileLock *lock=NULL;
long i, j;
char string[5];
/* Allocate 256 bytes as work memory */
if(!(sbuffer=SafeAllocMem(256L,MEMF_CLEAR|MEMF_PUBLIC)))
quit("No Work Memory!");
/* Check for and parse IFF data in first 256 bytes of file */
if(!(sFile=Open(sPath,MODE_OLDFILE)))
{
sactual=256L; quit("Can't Find SoundFile!");
}
Read(sFile,sbuffer,256L); /* load the 1st 256 bytes */
for(sstart=0L, sps=0L, i=0L; i<252L; i+=4L)
{
strncpy(string,sbuffer+i,4); string[4]=NULL;
if(!(strcmp(string,"VHDR"))) /* get samples per second */
{
for(j=0;j<(long)((UBYTE)sbuffer[i+20]);j++) sps+=256L;
sps += ((UBYTE)sbuffer[i+21L]);
}
if(!(strcmp(string,"CHAN"))) /* Channel Assignment */
{
if((sbuffer[i+7]==6)||(sbuffer[i+11]==6)) stereo=1;
}
if(!(strcmp(string,"BODY"))) /* get size of sound data */
{
for(j=0;j<4;j++) sactual+=(((UBYTE)sbuffer[i+7L-j])<<(8*j));
sstart = i+8L; i=252L;
}
}
/* if not in IFF format, get filesize from FileInfoBlock */
if(!sactual)
{
/* Allocate a file info block, get size from it, and de-allocate */
if((!(finfo=(struct FileInfoBlock *)